﻿using Myu.Redis.Init;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace commonFramwork.CacheManager
{
    public class CacheProvider: ICacheProvider,IDisposable
    {

        private readonly IRedisClient _cacheManager =  RedisManager.GetClient();
        static byte[] Serialize(object data)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream rems = new MemoryStream();
            formatter.Serialize(rems, data);
            return rems.GetBuffer();
        }
        static object Deserialize(byte[] data)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            MemoryStream rems = new MemoryStream(data);
            data = null;
            return formatter.Deserialize(rems);
        }
        public void Add(string key, string valKey, object value)
        {
            byte[] byteValue = Serialize(value);
            using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
            {
                Dictionary<string, byte[]> dict = null;
                if (tbl.ContainsKey(key))
                {
                    dict = (Dictionary<string, byte[]>)tbl.Lists[key][0];
                    dict[valKey] = byteValue;

                }
                else
                {
                    dict = new Dictionary<string, byte[]>();
                    dict.Add(valKey, byteValue);
                }
                Remove(key);
                tbl.Lists[key].Add(dict);
            }

        }

        public void Put(string key, string valKey, object value)
        {
            Add(key, valKey, value);
        }

        public object Get(string key, string valKey)
        {
            using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
            {
                if (tbl.ContainsKey(key))
                {
                    Dictionary<string, byte[]> dict = (Dictionary<string, byte[]>)tbl.Lists[key][0];
                    if (dict != null && dict.ContainsKey(valKey))
                        return Deserialize(dict[valKey]);
                    else
                        return null;
                }
            }
            return null;

        }

        public void Remove(string key)
        {
            using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
            {
                tbl.Lists[key].RemoveAll();
            }
        }

        public bool Exists(string key)
        {
            using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
            {
                return tbl.ContainsKey(key);
            }
        }

        public bool Exists(string key, string valKey)
        {
            using (var tbl = _cacheManager.GetTypedClient<Dictionary<string, byte[]>>())
            {
                return tbl.ContainsKey(key) &&
                 ((System.Collections.Generic.Dictionary<string, byte[]>)tbl.Lists[key][0]).ContainsKey(valKey);
            }
        }

        public void Dispose()
        {
            _cacheManager.Dispose();
        }

    }
}
